package emu.decvices.cartridge.mappers;

import emu.decvices.bus.BusDevice;
import emu.decvices.cartridge.Cartridge;

/**
 * 000号映射器
 *
 * -----------------------------------------------------------------------------------------------------------------------------------------------------------------------
 *
 * Overview
 * PRG ROM size: 16 KiB for NROM-128, 32 KiB for NROM-256 (DIP-28 standard pinout)
 * PRG ROM bank size: Not bankswitched
 * PRG RAM: 2 or 4 KiB, not bankswitched, only in Family Basic (but most emulators provide 8)
 * CHR capacity: 8 KiB ROM (DIP-28 standard pinout) but most emulators support RAM
 * CHR bank size: Not bankswitched, see CNROM
 * Nametable mirroring: Solder pads select vertical or horizontal mirroring
 * Subject to bus conflicts: Yes, but irrelevant
 *
 * 概述
 * PRG ROM 大小：NROM-128 为 16 KiB，NROM-256 为 32 KiB（DIP-28 标准引脚输出）
 * PRG ROM 存储体大小： 无库切换
 * PRG RAM：2 或 4 KiB，不可切换，仅在 Family Basic（但大多数仿真器提供 8 KiB）中使用
 * CHR 容量：8 KiB ROM（DIP-28 标准引脚），但大多数仿真器支持 RAM
 * CHR 存储体大小： 不可切换，参见 CNROM
 * 名称表镜像： 焊盘可选择垂直或水平镜像
 * 受总线冲突影响： 是，但无关紧要
 *
 * -----------------------------------------------------------------------------------------------------------------------------------------------------------------------
 *
 * Banks
 * All Banks are fixed,
 *
 * CPU $6000-$7FFF: Family Basic only: PRG RAM, mirrored as necessary to fill entire 8 KiB window, write protectable with an external switch
 * CPU $8000-$BFFF: First 16 KB of ROM.
 * CPU $C000-$FFFF: Last 16 KB of ROM (NROM-256) or mirror of $8000-$BFFF (NROM-128).
 *
 * 银行(Banks)  这里应该是将内容分片的意思
 * 所有Banks都是固定的、
 *
 * CPU $6000-$7FFF：仅限基本系列： PRG RAM，根据需要镜像以填充整个 8 KiB 窗口，可通过外部开关进行写保护
 * CPU $8000-$BFFF：前 16 KB ROM。
 * CPU $C000-$FFFF：最后 16 KB ROM（NROM-256）或 $8000-$BFFF 的镜像（NROM-128）。
 *
 *
 *-----------------------------------------------------------------------------------------------------------------------------------------------------------------------
 *
 * Solder pad config
 * Horizontal mirroring : 'H' disconnected, 'V' connected.
 * Vertical mirroring : 'H' connected, 'V' disconnected.
 * 焊盘配置
 * 水平镜像："H "断开，"V "连接。
 *
 *
 *
 *
 * 垂直镜像："H "连接，"V "断开。
 *
 *
 *-----------------------------------------------------------------------------------------------------------------------------------------------------------------------
 *
 *
 *
 *
 *
 *
 * Registers
 * None. This has normally no mapping capability whatsoever! Nevertheless, tile animation can be done by swapping between pattern tables $0000 and $1000, using PPUCTRL bits 4-3 as a "poor man's CNROM".
 *
 * 注册表
 * 无。通常不具备任何映射功能！不过，可以利用 PPUCTRL 第 4-3 位作为 "穷人的 CNROM"，通过在图案表 $0000 和 $1000 之间交换来实现磁贴动画。
 *
 *
 *
 *
 *
 *-----------------------------------------------------------------------------------------------------------------------------------------------------------------------
 *
 *Variants
 * RROM and SROM are NROM with different CHR ROM pinouts. RTROM and STROM split PRG into two 8KiB ROMs. HROM is an early NROM variant without the solder pads to select mirroring, only vertical mirroring available (as if the 'H' pad were selected).
 *
 * Family Basic, released by Nintendo, Sharp, and Hudson, contains 2 KiB WRAM (or 4 KiB WRAM for v3) accessible at $6000-$7FFF and decoded with a 74HC20, that is backed with 2 AA batteries. The cartridge is equipped with a back up switch that, when enabled, disables all access to WRAM in order to prevent possible data corruption when the Famicom is turned on or off.
 *
 * Galaxian uses a smaller 8KiB PRG ROM chip. iNES images are all therefore overdumps.
 *
 * Modern homebrew programs sometimes use mapper 0 with 8 KB of CHR RAM, which would not be supported on official NROM PCBs without rewiring. In theory, BNROM might be a more appropriate choice. But most emulators will do the right thing with a 16K or 32K PRG ROM with mapper 0.
 *
 * NROM-368 is a recent invention that allows addressing more memory without bank switching.
 *
 * 变体
 * RROM 和 SROM 是具有不同 CHR ROM 引脚布局的 NROM。RTROM 和 STROM 将 PRG 分成两个 8KB ROM。HROM 是早期的 NROM 变体，没有选择镜像的焊盘，只有垂直镜像（就像选择了 "H "焊盘）。
 *
 * 由任天堂、夏普和哈德逊发布的 Family Basic 包含 2 KiB WRAM（或 v3 的 4 KiB WRAM），可访问范围为 $6000至$7FFF，使用 74HC20 解码，支持 2 节 AA 电池。卡带配备了一个备份开关，启用后将禁止访问 WRAM，以防止 Famicom 开机或关机时可能出现的数据损坏。
 *
 * Galaxian 使用的是更小的 8KiB PRG ROM 芯片。
 *
 * 现代自制程序有时会使用带有 8 KB CHR RAM 的映射器 0，如果不重新布线，官方 NROM PCB 将不支持这种映射器。理论上，BNROM 可能是更合适的选择。但大多数仿真器都会正确使用 16K 或 32K PRG ROM 和映射器 0。
 *
 * NROM-368 是最近的一项发明，无需切换存储体即可寻址更多的存储体。
 */
public class Mapper000 extends Mapper{
    private CpuDevice cpuDevice = new CpuDevice();
    private PpuDevice ppuDevice = new PpuDevice();
    public Mapper000(Cartridge cartridge) {
        super(cartridge);
    }

    @Override
    public BusDevice getCpuDevice() {
        return cpuDevice;
    }

    @Override
    public BusDevice getPpuDevice() {
        return ppuDevice;
    }

    private class PpuDevice extends BusDevice{
        public boolean toDeviceWrite(int address, int data) {
            if (address >= 0x0000 && address <= 0x1FFF) {
                chrData[address] = (byte) (data & 0xFF);
                return true;
            }
            return false;
        }
        @Override
        public int fromDeviceRead(int address) {
            if(address>=0x0000&&address<=0x1FFF){
                return chrData[address]&0xFF;
            }
            return -1;
        }
    }

    private class CpuDevice extends BusDevice{
        @Override
        public int fromDeviceRead(int address) {
            //CPU可寻址prgRom的总线地址范围
            if(address>=0x8000 && address<=0xFFFF) {
                //PRG只有1块时，后16k地址映射为前16k地址
                if(romHeader.getPrgRomChunks()>1){
                    return prgData[address&0x7FFF]&0xFF;
                }else{
                    return prgData[address&0x3FFF]&0xFF;
                }
            }
            return -1;
        }
    }
}
